/**
 * This file is part of XaMauLo 
 * File :                       SchemaXML.scala
 * Author's email :             laure.conte@gmail.com
 *                              sophie.couillez@gmail.com
 **/

package utils;

import scala.xml.include.sax._;
import scala.xml._;
import scala.collection.mutable.HashMap;
import scala._;
import objects.Element;
import main.Validator;
import org.xml.sax.Locator;
import org.xml.sax.helpers.LocatorImpl;

/**
  * This class permit to browse the XML file like SAX and verify if the element is in the XSD
 */

class ParcoursXML(valid:Validator) extends XIncludeFilter {
  //liste des pr�c�dents (parents)
  var listPreceeding : List[String]=List();
  //liste des fils;
  var listSons : List[String]=List();
  
  //HashMap regroupant le noeud parent et la liste de ses fils correspondants
  var listFils : HashMap[String,List[String]]=new HashMap[String,List[String]];
  

  //Noeud pr�c�dent (parent)

  var preceeding="";
  
  var valueCourant : String="";
  
  var attributs :HashMap[String,HashMap[String,String]]=new HashMap[String,HashMap[String,String]];
  
  var listAttributs : HashMap[String,String]=new HashMap[String,String];
  var locator : Locator=new LocatorImpl;
  var lines : HashMap[String,List[int]]=new HashMap[String,List[int]];
  
  
 override def setDocumentLocator(value : Locator) {
    locator =  value;
}
  
 //d�but du document 
 override def startDocument : Unit={
   println("Document XML");
 }
 

 //permet d'afficher les donn�es contenues dans les balises
 override def characters(ch : Array[Char], start : Int, length : Int) = {
    valueCourant=new String(ch,start,length);
   // println(testType(new String(ch,start,length),"integer"));
    
}


 //d�but de l'�l�ment
 override def startElement(namespaceURI :String, localName : String, qualifiedName : String, atts : org.xml.sax.Attributes)={
  
   lines+=((localName,List(locator.getLineNumber,locator.getColumnNumber)));
  var i =0; 
  listAttributs=new HashMap[String,String];

  //on ajoute l'�l�ment � la liste des balises
  listFils+=((localName,List()));
  

  //on ajoute � la liste des parents le noeud courant
  listPreceeding=localName::listPreceeding;
  

  //on initialise le noeud pr�c�dent � la valeur de la racine
  if(preceeding.equals("")){
    preceeding=localName;
  }
  
  while(i<atts.getLength){
    listAttributs+=((atts.getQName(i),atts.getValue(i)));
    i+=1; 
  }
  attributs+=((localName,listAttributs));
}
 
 override def endElement  (namespaceURI : java.lang.String, localName : java.lang.String, qualifiedName : java.lang.String) : Unit={
  
 testListVide(localName);
 listAttributs=attributs{localName};
 
 val tmpPreceeding : List[String]=localName :: listPreceeding;
 val ligne=lines(localName).head;
 val column=lines(localName).last;
 val elt= new Element(localName,valueCourant,listFils(localName).reverse,tmpPreceeding.reverse,listAttributs,ligne,column);
 valid.verification(elt);
 }

 override def endDocument()={

    
}

 def ajoutListFils(localName:String): Unit = listPreceeding match{
   case List() if listFils.contains(preceeding)=>listSons=listSons ::: listFils(preceeding);listFils+=((preceeding,listSons)); 
   case _ if  !listPreceeding.isEmpty &&listPreceeding.head.equals(preceeding)=>listSons=localName :: listSons;
   case _ if listFils.contains(preceeding)=>listSons=listSons ::: listFils(preceeding); listFils+=((preceeding,listSons));listSons=List();listSons=localName::listSons;if(!listPreceeding.isEmpty)preceeding=listPreceeding.head;
   case _  =>listFils+=((preceeding,listSons));listSons=List();listSons=localName::listSons;if(!listPreceeding.isEmpty)preceeding=listPreceeding.head;
  
 }
 
 def testListVide (localName:String): Unit = listPreceeding match{
   case List() =>
   case _ if listPreceeding.contains(localName) =>listPreceeding=listPreceeding.tail;ajoutListFils(localName);
 }
 
// def testType(typeNoeud : String,typeXSD : String):String = typeXSD match{
//}

}
